package com.charges.util;

import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;

/**
 * @author cbk
 * @version v1.0
 * @ClassName SignUtils
 * @Date: 2025/6/9 22:48
 * @Description: 生成签名算法
 */
public class SignUtils {

    /**
     * 为了防止API调用过程中被恶意篡改，调用任何一个API都需要携带请求签名，开放平台服务端会根据请求参数，对签名进行验证，并对签名不合法的请求将会被拒绝。
     *
     * 目前支持的签名算法为：MD5(sign_method=md5)，签名过程如下：
     *
     * 本次请求中所有请求参数（包含公共参数与业务参数）进行首字母以ASCII方式升序排列（ASCII ASC），对于相同字母则使用下个字母做二次排序，字母序为从左到右，以此类推
     *
     * 排序后的结果按照参数名（key）参数值（value）的次序进行字符串拼接，拼接处不包含任何字符
     *
     * 拼接完成的字符串做进一步拼接成1个字符串（包含所有kv字符串的长串），并在该长串的头部及尾部分别拼接appSecret，完成签名字符串的组装
     *
     * 最后对签名字符串，使用MD5算法加密后，得到的MD5加密密文后转为大写，即为sign值
     *
     *  注意：若value为array/list时，value请勿拼接，只保留key即可。
     */
    public static String getSign(String appSecret, Map<String, Object> params) {
        // 将HashMap转换为TreeMap，TreeMap会自动对键排序
        TreeMap<String, Object> sortedMap = new TreeMap<>(params);
        StringBuilder sb = new StringBuilder();
        sb.append(appSecret);
        sortedMap.forEach((k, v) -> {
            sb.append(k);
            sb.append(v);
        });
        sb.append(appSecret);
        return Objects.requireNonNull(MD5Utils.code(sb.toString())).toUpperCase();
    }
}
